﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace System.Linq
{
  public static class ObjectExtensions
  {
    public static IEnumerable<T> Traverse<T>(this T obj, Func<T, T> child)
    {
      T cursor = obj;
      do
      {
        yield return cursor;
        cursor = child(cursor);
      } while (cursor != null);
    }

    public static IEnumerable<T> Traverse<T>(this IEnumerable<T> obj, Func<IEnumerable<T>, IEnumerable<T>> child)
    {
      IEnumerable<T> cursor = obj;
      List<T> ret = new List<T>();
      do
      {
        ret.AddRange(cursor);
        cursor = child(cursor);
      } while (cursor != null);

      return ret;
    }

    public static IEnumerable<T> Traverse<T>(this T obj, Func<T, IEnumerable<T>> child, bool inclusive = true)
    {
      List<T> ret = new List<T>();
      if (inclusive)
        ret.Add(obj);

      foreach(T item in child(obj))
        ret.AddRange(item.Traverse(child, false));

      return ret;
    }

  }
}
